/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainFrame.java
 *
 * Created on 26/09/2009, 13:30:52
 */

package saintseiya.view;

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

public class MainFrame extends javax.swing.JFrame {
	private static final long serialVersionUID = -1143704027723948446L;

	// persistent settings
	public static final String PROP_FILE = "properties.ini";
	public static final String LAST_DIR_KEY = "lastDir";
	public static final String DEFAULT_LAST_DIR = System.getProperty("user.home");
	private static final String RECENT_KEY = "recent";
	private static final String RECENT_SB_KEY = RECENT_KEY + "SB"; // start byte
	private static final String RECENT_EB_KEY = RECENT_KEY + "EB"; // end byte
	private static final int MAX_RECENT = 5;
	// font settings
	private static final String FONT = "Arial Unicode MS";
	private static final int FONT_SIZE = 20;
	private static final Color FONT_EDIT_COLOR = Color.RED;
	// file settings
	private static final String FILE_ERROR_MESSAGE = "Can't operate on this file.";
	public static final String ENCODING = "UTF-16LE";
	private static final String SAVE_SUFFIX = "_TR";
	// editor settings
	private static final String CHARS_PATTERN = "[\\u0020-\\u007e\\u00c0-\\u00fe]";

	private Properties props;
	private JMenuItem[] recentItems;
	private File openFile;
	private int startByte;
	private int endByte;
	private Document doc;
	private SimpleAttributeSet attributeSet;

    public MainFrame() {
		try {
			// initialize with default values
			this.props = new Properties();
			this.props.setProperty(LAST_DIR_KEY, DEFAULT_LAST_DIR);
			for ( int i = 1; i <= MAX_RECENT; i++ ) {
				this.props.setProperty(RECENT_KEY + i, "");
				this.props.setProperty(RECENT_SB_KEY + i, "");
				this.props.setProperty(RECENT_EB_KEY + i, "");
			}
			// try to load values from file
			this.props.load(new FileReader(PROP_FILE));
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		initComponents();
		this.setLocationRelativeTo(null);

		// makes easy to manage recent files
		this.recentItems = new JMenuItem[MAX_RECENT + 1];
		this.recentItems[1] = this.recent1MenuItem;
		this.recentItems[2] = this.recent2MenuItem;
		this.recentItems[3] = this.recent3MenuItem;
		this.recentItems[4] = this.recent4MenuItem;
		this.recentItems[5] = this.recent5MenuItem;

		// set recent files menu
		for(int i = 1; i <= MAX_RECENT; i++) {
			if ( this.props.getProperty(RECENT_KEY + i) != null && !this.props.getProperty(RECENT_KEY + i).equals("") ) {
				this.recentItems[i].setText( i + " " + new File(this.props.getProperty(RECENT_KEY + i)).getName() );
				this.recentItems[i].setEnabled(true);
			}
		}

		// font settings
		this.attributeSet = new SimpleAttributeSet();
		StyleConstants.setForeground(this.attributeSet, FONT_EDIT_COLOR);
		StyleConstants.setFontFamily(attributeSet, FONT);
		StyleConstants.setFontSize(attributeSet, FONT_SIZE);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        fileChooser = new javax.swing.JFileChooser();
        filePanel = new javax.swing.JPanel();
        fileLabel = new javax.swing.JLabel();
        fileTextField = new javax.swing.JTextField();
        chooseFileButton = new javax.swing.JButton();
        startLabel = new javax.swing.JLabel();
        startTextField = new javax.swing.JTextField();
        endLabel = new javax.swing.JLabel();
        endTextField = new javax.swing.JTextField();
        openButton = new javax.swing.JButton();
        saveButton = new javax.swing.JButton();
        editorPanel = new javax.swing.JPanel();
        editorScrollPane = new javax.swing.JScrollPane();
        editorPane = new javax.swing.JEditorPane();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        chooseFileMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        recent1MenuItem = new javax.swing.JMenuItem();
        recent2MenuItem = new javax.swing.JMenuItem();
        recent3MenuItem = new javax.swing.JMenuItem();
        recent4MenuItem = new javax.swing.JMenuItem();
        recent5MenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JSeparator();
        exitMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        contentsMenuItem = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JSeparator();
        aboutMenuItem = new javax.swing.JMenuItem();

        fileChooser.setCurrentDirectory(new File( this.props.getProperty(LAST_DIR_KEY) ));
        fileChooser.setDialogTitle("Open message file");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Saint Seiya message translator");

        fileLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        fileLabel.setText("File:");

        fileTextField.setEditable(false);

        chooseFileButton.setText("Choose...");
        chooseFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chooseFileButtonActionPerformed(evt);
            }
        });

        startLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        startLabel.setText("Start byte:");

        startTextField.setText("1");
        startTextField.setPreferredSize(new java.awt.Dimension(40, 20));

        endLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        endLabel.setText("End byte:");

        endTextField.setPreferredSize(new java.awt.Dimension(40, 20));

        openButton.setText("Open");
        openButton.setEnabled(false);
        openButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openButtonActionPerformed(evt);
            }
        });

        saveButton.setText("Save");
        saveButton.setEnabled(false);
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout filePanelLayout = new javax.swing.GroupLayout(filePanel);
        filePanel.setLayout(filePanelLayout);
        filePanelLayout.setHorizontalGroup(
            filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(fileLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(startLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filePanelLayout.createSequentialGroup()
                        .addComponent(fileTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 282, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(chooseFileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(filePanelLayout.createSequentialGroup()
                        .addComponent(startTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(endLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(endTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(openButton)
                        .addGap(18, 18, 18)
                        .addComponent(saveButton)))
                .addContainerGap())
        );
        filePanelLayout.setVerticalGroup(
            filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(fileLabel)
                    .addComponent(chooseFileButton)
                    .addComponent(fileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(startTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(startLabel)
                    .addComponent(endLabel)
                    .addComponent(endTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(openButton)
                    .addComponent(saveButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        editorPanel.setBackground(new java.awt.Color(102, 255, 51));

        editorPane.setContentType("text/rtf");
        editorPane.setEnabled(false);
        this.doc = this.editorPane.getDocument();
        editorPane.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                editorPaneKeyPressed(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                editorPaneKeyTyped(evt);
            }
        });
        editorScrollPane.setViewportView(editorPane);

        javax.swing.GroupLayout editorPanelLayout = new javax.swing.GroupLayout(editorPanel);
        editorPanel.setLayout(editorPanelLayout);
        editorPanelLayout.setHorizontalGroup(
            editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(editorScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 486, Short.MAX_VALUE)
        );
        editorPanelLayout.setVerticalGroup(
            editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(editorScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE)
        );

        fileMenu.setText("File");

        chooseFileMenuItem.setText("Choose...");
        chooseFileMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chooseFileMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(chooseFileMenuItem);
        fileMenu.add(jSeparator1);

        recent1MenuItem.setText("1 <empty>");
        recent1MenuItem.setEnabled(false);
        recent1MenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recent1MenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(recent1MenuItem);

        recent2MenuItem.setText("2 <empty>");
        recent2MenuItem.setEnabled(false);
        recent2MenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recent2MenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(recent2MenuItem);

        recent3MenuItem.setText("3 <empty>");
        recent3MenuItem.setEnabled(false);
        recent3MenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recent3MenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(recent3MenuItem);

        recent4MenuItem.setText("4 <empty>");
        recent4MenuItem.setEnabled(false);
        recent4MenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recent4MenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(recent4MenuItem);

        recent5MenuItem.setText("5 <empty>");
        recent5MenuItem.setEnabled(false);
        recent5MenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recent5MenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(recent5MenuItem);
        fileMenu.add(jSeparator2);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText("Help");

        contentsMenuItem.setText("Contents...");
        helpMenu.add(contentsMenuItem);
        helpMenu.add(jSeparator3);

        aboutMenuItem.setText("About...");
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(filePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(editorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(filePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(editorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void chooseFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseFileButtonActionPerformed
        int response = this.fileChooser.showOpenDialog(this);
        if ( response == JFileChooser.APPROVE_OPTION ) {
            try {
                File f = this.fileChooser.getSelectedFile();
                if ( f.isFile() && !f.isHidden() && f.canRead() && f.canWrite() ) {
					this.fileTextField.setText( f.getAbsolutePath() );
					this.startTextField.setText("1");
					this.endTextField.setText( f.length() + "" );
					this.openButton.setEnabled(true);
                }
                else {
                    throw new Exception(FILE_ERROR_MESSAGE);
                }
            }
            catch( Exception e ) {
				this.openButton.setEnabled(false);
                this.showError( e );
            }
        }
    }//GEN-LAST:event_chooseFileButtonActionPerformed

    private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
		try {
			// open file
			this.openFile = new File( fileTextField.getText() );
			// set bytes
			this.startByte = Integer.parseInt( this.startTextField.getText() );
			this.endByte = Integer.parseInt( this.endTextField.getText() );
			// check bytes
			if( this.startByte < 1 || this.endByte > this.openFile.length() || this.endByte < startByte ) {
				throw new Exception("Invalid start or end bytes.");
			}

			// read file
			FileInputStream fis = new FileInputStream( this.openFile );
			// skip initial bytes
			fis.skip(this.startByte - 1);
			// read middle bytes
			int limit = this.endByte - this.startByte + 1;
			byte[] buffer = new byte[limit];
			fis.read(buffer);
			fis.close();

			// set font
			SimpleAttributeSet as = new SimpleAttributeSet();
			StyleConstants.setFontFamily(as, FONT);
			StyleConstants.setFontSize(as, FONT_SIZE);
			// clean editor
			this.doc.remove(0, this.doc.getLength());
			// insert text
			this.doc.insertString(0, new String(buffer,ENCODING), as);
			this.editorPane.setCaretPosition(0);

			this.editorPane.setEnabled(true);
			this.saveButton.setEnabled(true);

			// update recent list
			if( !this.openFile.getAbsolutePath().equals(this.props.getProperty(RECENT_KEY + 1))
				|| ""+this.startByte != this.props.getProperty(RECENT_SB_KEY + 1)
				|| ""+this.startByte != this.props.getProperty(RECENT_EB_KEY + 1)) {

				for( int i = MAX_RECENT - 1; i >= 1; i-- ) {
					// shifts recent files down
					this.props.setProperty(RECENT_KEY + (i + 1), this.props.getProperty(RECENT_KEY + i));
					this.props.setProperty(RECENT_SB_KEY + (i + 1), this.props.getProperty(RECENT_SB_KEY + i));
					this.props.setProperty(RECENT_EB_KEY + (i + 1), this.props.getProperty(RECENT_EB_KEY + i));
				}
				// current file takes first slot
				this.props.setProperty(RECENT_KEY + 1, this.openFile.getAbsolutePath());
				this.props.setProperty(RECENT_SB_KEY + 1, "" + this.startByte);
				this.props.setProperty(RECENT_EB_KEY + 1, "" + this.endByte);
			}
			this.props.setProperty(LAST_DIR_KEY, this.openFile.getParent());
			// persist properties
			this.props.store(new FileWriter(PROP_FILE), null);
		}
		catch( Exception e ) {
			this.editorPane.setEnabled(false);
			this.saveButton.setEnabled(false);
			this.showError( e );
		}
    }//GEN-LAST:event_openButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
		try {
			// original file
			FileInputStream fis = new FileInputStream( this.openFile );
			// output file
			File outputFile = new File( this.openFile.getParentFile(), this.openFile.getName() + SAVE_SUFFIX );
			FileOutputStream fos = new FileOutputStream(outputFile);

			// write initial bytes from original file
			byte[] buffer = new byte[ this.startByte - 1 ];
			fis.read(buffer);
			fos.write(buffer);

			// write middle bytes from editor
			String editText = this.doc.getText(0, this.doc.getLength());
			fos.write(editText.getBytes(ENCODING));

			// write last bytes from original file
			int limit = this.endByte - this.startByte + 1;
			fis.skip( limit );
			buffer = new byte[ (int)this.openFile.length() - this.endByte ];
			fis.read(buffer);
			fos.write(buffer);

			fos.flush();
			fos.close();
		}
		catch( Exception e ) {
			this.showError( e );
		}
    }//GEN-LAST:event_saveButtonActionPerformed

	private void chooseFileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseFileMenuItemActionPerformed
		this.chooseFileButton.doClick();
	}//GEN-LAST:event_chooseFileMenuItemActionPerformed

	private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
		this.dispose();
	}//GEN-LAST:event_exitMenuItemActionPerformed

	private void editorPaneKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_editorPaneKeyTyped
		try {
			evt.consume();
			String key = evt.getKeyChar() + "";
			// if the input is invalid
			if ( !key.matches(CHARS_PATTERN) ) {
				return;
			}

			if ( this.editorPane.getCaretPosition() < this.doc.getLength() ) {
				// if the text being overwritten is valid
				String ch = this.doc.getText(this.editorPane.getCaretPosition(), 1);
				if ( ch.matches(CHARS_PATTERN) ) {
					// overwrite char
					this.doc.remove(this.editorPane.getCaretPosition(), 1);
					this.doc.insertString(this.editorPane.getCaretPosition(), key, this.attributeSet);
				}
				else {
					// skip char and move caret
					this.editorPane.setCaretPosition( this.editorPane.getCaretPosition() + 1 );
				}
			}
		}
		catch( Exception e ) {
			this.showError(e);
		}
	}//GEN-LAST:event_editorPaneKeyTyped

	private void editorPaneKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_editorPaneKeyPressed
		try {
			int codigo = evt.getKeyCode();
			if ( codigo == KeyEvent.VK_BACK_SPACE ) {
				evt.consume();
				if ( this.editorPane.getCaretPosition() > 0 ) {
					String ch = this.doc.getText(this.editorPane.getCaretPosition() - 1, 1);
					if ( ch.matches(CHARS_PATTERN) ) {
						this.doc.remove(this.editorPane.getCaretPosition() - 1, 1);
						this.doc.insertString(this.editorPane.getCaretPosition(), " ", this.attributeSet);
					}
					this.editorPane.setCaretPosition( this.editorPane.getCaretPosition() - 1 );
				}
			}
			if ( codigo == KeyEvent.VK_DELETE || codigo == KeyEvent.VK_ENTER ) {
				evt.consume();
			}
		}
		catch( Exception e ) {
			this.showError(e);
		}
	}//GEN-LAST:event_editorPaneKeyPressed

	private void recent1MenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recent1MenuItemActionPerformed
		this.loadRecent(1);
	}//GEN-LAST:event_recent1MenuItemActionPerformed

	private void recent2MenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recent2MenuItemActionPerformed
		this.loadRecent(2);
	}//GEN-LAST:event_recent2MenuItemActionPerformed

	private void recent3MenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recent3MenuItemActionPerformed
		this.loadRecent(3);
	}//GEN-LAST:event_recent3MenuItemActionPerformed

	private void recent4MenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recent4MenuItemActionPerformed
		this.loadRecent(4);
	}//GEN-LAST:event_recent4MenuItemActionPerformed

	private void recent5MenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recent5MenuItemActionPerformed
		this.loadRecent(5);
	}//GEN-LAST:event_recent5MenuItemActionPerformed

	private void loadRecent( int num ) {
		try {
			File f = new File( this.props.getProperty(RECENT_KEY + num) );
			if ( f.isFile() && !f.isHidden() && f.canRead() && f.canWrite() ) {
				this.fileTextField.setText( f.getAbsolutePath() );
				this.startTextField.setText(this.props.getProperty(RECENT_SB_KEY + num));
				this.endTextField.setText(this.props.getProperty(RECENT_EB_KEY + num));
				this.openButton.setEnabled(true);
			}
			else {
				throw new Exception(FILE_ERROR_MESSAGE);
			}
		}
		catch( Exception e ) {
			this.openButton.setEnabled(false);
			this.showError( e );
		}
	}

	private void showError( Exception e ) {
		JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JButton chooseFileButton;
    private javax.swing.JMenuItem chooseFileMenuItem;
    private javax.swing.JMenuItem contentsMenuItem;
    private javax.swing.JEditorPane editorPane;
    private javax.swing.JPanel editorPanel;
    private javax.swing.JScrollPane editorScrollPane;
    private javax.swing.JLabel endLabel;
    private javax.swing.JTextField endTextField;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JLabel fileLabel;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JPanel filePanel;
    private javax.swing.JTextField fileTextField;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JButton openButton;
    private javax.swing.JMenuItem recent1MenuItem;
    private javax.swing.JMenuItem recent2MenuItem;
    private javax.swing.JMenuItem recent3MenuItem;
    private javax.swing.JMenuItem recent4MenuItem;
    private javax.swing.JMenuItem recent5MenuItem;
    private javax.swing.JButton saveButton;
    private javax.swing.JLabel startLabel;
    private javax.swing.JTextField startTextField;
    // End of variables declaration//GEN-END:variables

}
